<?php
/**
 * author by OCY, 2022/01/19 16:09.
 */

namespace app\index\controller;

use mikkle\tp_redis\Redis;

class Study
{
    /**
     * @param $params    array 请求参数（注意：请求参数必须携带timestamp，timestamp为当前时间戳，单位：秒）
     * @param $secretKey string 密钥（U2FsdGVkX1+P7gZjqas4vYb/lEdnwcE6jjcRvE4cjTpr9BuE9pdJmVGEbnainTMntpp+sGRLem0JC/k2HwW4jA==）
     * */
    function generateSign($params, $secretKey)
    {
        // 删除已有的 sign 参数（防止影响签名）
        if (isset($params['sign'])) {
            unset($params['sign']);
        }

        // 按 key 排序
        ksort($params);

        // 生成 query 字符串
        $str = http_build_query($params);

        // 计算 HMAC-SHA256 签名（返回十六进制字符串）
        $sign = hash_hmac('sha256', $str, $secretKey);

        return $sign;
    }

    public function test()
    {
        $data = [
            'name' => 'Dave',
            'timestamp' => time()
        ];
        $secretKey = 'U2FsdGVkX1+P7gZjqas4vYb/lEdnwcE6jjcRvE4cjTpr9BuE9pdJmVGEbnainTMntpp+sGRLem0JC/k2HwW4jA==';
        $sign = $this->generateSign($data, $secretKey);
        $data['sign'] = $sign;

        // 发起请求
        $res = httpsRequest('http://fund.funshappy.com/index/Api/testApi', $data);
        echo "<pre>";
        print_r($res);
        exit;
    }

    public function testRedis()
    {
        // index => 指定第几个Redis数据库，下标从0开始
        $redis = Redis::instance(['index' => 3]);
        $redis->set("name", "This is mikkle's redis4");
        echo "<pre>";
        print_r($redis->get("name"));
        exit;
    }

    /******************** 秒杀 START ********************/

    /**
     * 1：先访问addKillGoods添加秒杀商品
     * 2：Apache的ab压测工具请求goodsKill模拟秒杀商品
     * 3：访问killResult查看redis结果
     * */

    /**
     * 添加秒杀商品
     * */
    public function addKillGoods()
    {
        $goods_count = 30;
        $key = '20220219_goods_list';

        $redis = redis::instance();
        for ($i = 1; $i <= $goods_count; $i++) {
            $redis->rPush($key, $i);
        }
    }

    /**
     * 秒杀
     * */
    public function goodsKill()
    {
        //假装是用户的唯一标识
        $uuid = md5(uniqid('user') . time());
        //创建连接redis对象
        $redis = redis::instance();
        $listKey = "20220219_goods_list";
        $orderKey = "20220219_buy_order";
        $failUserNum = "20220219_fail_user_num";
        if ($goodsId = $redis->lPop($listKey)) {
            //秒杀成功
            //将幸运用户存在集合中
            $redis->hSet($orderKey, $goodsId, $uuid);
        } else {
            //秒杀失败
            //将失败用户计数
            $redis->incre($failUserNum);
        }
        echo "SUCCESS";
    }

    public function killResult()
    {
        $redis = Redis::instance();

        echo "<pre>";
        print_r('成功秒杀用户列表');
        print_r($redis->hGet('20220219_buy_order'));
        print_r('秒杀失败用户数量：' . $redis->get('20220219_fail_user_num'));
        exit;
    }
    /******************** 秒杀 END ********************/
}